package org.bigk.invoices.actions.invoicespositions;

import java.util.List;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.bigk.invoices.actions.AbstractCRUDAction;
import org.bigk.invoices.actions.invoices.InvoicesActionHelper;
import org.bigk.invoices.exceptions.ServiceException;
import org.bigk.invoices.model.Invoice;
import org.bigk.invoices.model.InvoicePosition;
import org.bigk.invoices.model.PaymentKind;
import org.bigk.invoices.model.Tax;
import org.bigk.invoices.services.InvoicesPositionsService;
import org.bigk.invoices.services.InvoicesService;
import org.bigk.invoices.services.PaymentKindsService;
import org.bigk.invoices.services.TaxesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;


@Controller("invoicesPositionsAction")
@Namespace("/invoicesPositions")
public class InvoicesPositionsAction extends AbstractCRUDAction<InvoicePosition> {

	private static final long serialVersionUID = 3190832719110023997L;
	private static final Logger logger = LoggerFactory.getLogger(InvoicesPositionsAction.class);
	
	public static final String BACK_INVOICES_INPUT = "backInvoicesInput";
	
	@Autowired
	private InvoicesService invoicesService;
	
	@Autowired
	private InvoicesPositionsService invoicesPositionsService;
	
	@Autowired
	private PaymentKindsService paymentKindsService;
	
	@Autowired
	private TaxesService taxesService;

	private Long id;
	private Long pId;
	private Invoice invoice;
	
	private List<PaymentKind> paymentKindsList;
	private List<Tax> taxesList;
	
	@Override
	public void prepare() throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("prepare() - start");
		}

		this.invoice = InvoicesActionHelper.retrieveInvoiceFromSession();

		this.paymentKindsList = this.paymentKindsService.listAllItems();
		this.taxesList = this.taxesService.listAllItems(invoice.getPaymentDate());

		if (logger.isDebugEnabled()) {
			logger.debug("prepare() - end");
		}
	}
	
	@Override
	public void prepareCreate() throws ServiceException {
		this.model = this.invoicesPositionsService.prepareNewInvoicePosition();
	}

	@Action(value = "create",
			results = {
					@Result(name = INPUT, location = "/pages/invoicesPositions/input.jsp")
			})
	@Override
	public String create() throws ServiceException {
		return super.create();
	}
	
	@Override
	public void prepareEdit() throws ServiceException {
		logger.debug("prepareEdit() - start");
		
		this.invoice = InvoicesActionHelper.retrieveInvoiceFromSession();
		this.model = invoicesService.getInvoicePosition(this.invoice, this.pId);

		logger.debug("prepareEdit() - end");
	}

	@Action(value = "edit",
			results = {
					@Result(name = INPUT, location = "/pages/invoicesPositions/input.jsp")
			})
	@Override
	public String edit() throws ServiceException {
		return super.edit();
	}
	
	@Override
	public void prepareSave() throws ServiceException {
		logger.debug("prepareSave() - start");

		this.model = new InvoicePosition();

		logger.debug("prepareSave() - end");
	}

	@Action(value = "save",
			results = {
					@Result(name = BACK_INVOICES_INPUT,
							type = "redirectAction",
							params = {"namespace", "/invoices", "actionName", "createEditRefresh"})
			}
	)
	@Override
	public String save() throws ServiceException {
		logger.debug("save() - start");

		this.invoicesService.addInvoicePosition(this.invoice, this.model);
		
		logger.debug("save() - end - return value=[{}]", BACK_INVOICES_INPUT);
		return BACK_INVOICES_INPUT;
	}

	@Override
	public void prepareUpdate() throws ServiceException {
		logger.debug("prepareUpdate() - start");

		this.invoice = InvoicesActionHelper.retrieveInvoiceFromSession();
		this.model = invoicesService.getInvoicePosition(this.invoice, this.pId);

		logger.debug("prepareUpdate() - end");
	}
	
	@Action(value = "update",
			results = {
					@Result(name = BACK_INVOICES_INPUT,
							type = "redirectAction",
							params = {"namespace", "/invoices", "actionName", "createEditRefresh"})
			}
	)
	@Override
	public String update() throws ServiceException {
		logger.debug("update() - start");

		invoicesService.updateInvoicePosition(this.invoice, this.model, pId);
		addActionMessage(getText("msg.recordUpdatedSuccess"));

		logger.debug("update() - end - return value=[{}]", BACK_INVOICES_INPUT);
		return BACK_INVOICES_INPUT;
	}
	
	public void prepareBackToInvoice() throws ServiceException {
		logger.debug("prepareBackToInvoice() - start");

		this.invoice = InvoicesActionHelper.retrieveInvoiceFromSession();
		
		if (pId != null) {
			this.model = invoicesService.getInvoicePosition(this.invoice, pId);
		} else {
			this.model = new InvoicePosition();
		}

		logger.debug("prepareBackToInvoice() - end");
	}

	@Action(value = "backToInvoice",
			results = {
				@Result(name = BACK_INVOICES_INPUT,
						type = "redirectAction",
						params = {"namespace", "/invoices", "actionName", "createEditRefresh"})
			}
	)
	@SkipValidation
	public String backToInvoice() throws ServiceException {
		logger.debug("backToInvoice() - start - end - return value=[{}]", BACK_INVOICES_INPUT);
		return BACK_INVOICES_INPUT;
	}

	public Invoice getInvoice() {
		return invoice;
	}

	public void setInvoice(Invoice invoice) {
		this.invoice = invoice;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Long getPId() {
		return pId;
	}

	public void setPId(Long id) {
		pId = id;
	}

	public List<PaymentKind> getPaymentKindsList() {
		return paymentKindsList;
	}

	public void setPaymentKindsList(List<PaymentKind> paymentKindsList) {
		this.paymentKindsList = paymentKindsList;
	}
	
	public List<Tax> getTaxesList() {
		return taxesList;
	}

	public void setTaxesList(List<Tax> taxesList) {
		this.taxesList = taxesList;
	}
}
